﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla;
using BizControl.DalLinq;
using BizControl.Library.Helpers;

namespace BizControl.Library.BusinessObjects.Activities
{
  [Serializable()]
  public class ActivityInfo : ReadOnlyBase<ActivityInfo>, ISupportEmptyValue
  {
    private readonly int ShortNameLength = 30;

    public Guid Id { get; private set; }
    public string Description { get; private set; }
    public int Progress { get; private set; }
    public ActivityState State { get; private set; }
    public DateTime? StartDate { get; set; }
    public DateTime? DueDate { get; set; }
    public DateTime? EndDate { get; set; }
    public DateTime CreatedOn { get; set; }

    public string VeryShortDescription
    {
      get { return StringHelper.GetShortenDescription(Description, ShortNameLength); }
    }

    public string ShortenDescription
    {
      get { return this.GetShortenDescription(); }
    }

    public override string ToString()
    {
      return ShortenDescription;
    }

    internal ActivityInfo()
    { /* require use of factory methods */ }

    internal ActivityInfo(Activity activity)
    {
      if (activity != null)
      {
        Id = activity.ActivityId;
        Description = activity.Description;
        Progress = activity.Progress;
        StartDate = activity.StartDate;
        DueDate = activity.DueDate;
        EndDate = activity.Ended;
        CreatedOn = activity.CreatedOn;
        FillState(activity);
      }
    }

    internal ActivityInfo(ActivityBO activity)
    {
      if (activity != null)
      {
        Id = activity.ActivityId;
        Description = activity.Description;
        Progress = activity.Progress;
        StartDate = activity.StartDate;
        DueDate = activity.DueDate;
        EndDate = activity.Ended;
        CreatedOn = activity.CreatedOn;
        State = activity.State;
      }
    }

    internal ActivityInfo(ActivityInfo activity)
    {
      if (activity != null)
      {
        Id = activity.Id;
        Description = activity.Description;
        Progress = activity.Progress;
        StartDate = activity.StartDate;
        DueDate = activity.DueDate;
        EndDate = activity.EndDate;
        CreatedOn = activity.CreatedOn;
        State = activity.State;
      }
    }

    public override bool Equals(object obj)
    {
      if (obj is ActivityInfo)
        return this.Id == (obj as ActivityInfo).Id;
      return base.Equals(obj);
    }

    public override int GetHashCode()
    {
      return base.GetHashCode();
    }

    private void FillState(Activity activity)
    {
      if (activity.IsCompleted) State = ActivityState.Completed;
      else State = ActivityState.Normal;
      if ((!activity.IsCompleted && activity.DueDate < DateTime.Now)
          || (activity.IsCompleted && activity.DueDate < activity.Ended)) State = State | ActivityState.Overdue;
      ActivityLink previousActivity = 
        activity.ActivityLinks1.Where(a => ((ActivityLinkType)Enum.Parse(typeof(ActivityLinkType), a.Condition)) == ActivityLinkType.Next).FirstOrDefault();
      ActivityLink parentActivity = 
        activity.ActivityLinks1.Where(a => ((ActivityLinkType)Enum.Parse(typeof(ActivityLinkType), a.Condition)) == ActivityLinkType.Child).FirstOrDefault();
      ActivityInfo parentActivityInfo = null;
      if (parentActivity != null) parentActivityInfo = new ActivityInfo(parentActivity.Activity1Ref);
      if ((!activity.IsCompleted && activity.StartDate > DateTime.Now)
        || (previousActivity != null && !previousActivity.Activity1Ref.IsCompleted)
        || (parentActivityInfo != null && !parentActivityInfo.IsEmpty() && parentActivityInfo.State.HasFlag(ActivityState.NotStarted)))
        State = State | ActivityState.NotStarted;
    }

    #region ISupportEmtpyValue Members

    public bool IsEmpty()
    {
      return Id == Guid.Empty;
    }

    #endregion
  }
}
